added more fields to allow more interesting iterators. Also, made the
authorJonathan Blandford <jrb@redhat.com>
Thu, 9 Nov 2000 16:52:17 +0000 (16:52 +0000)
committerJonathan Blandford <jrb@src.gnome.org>
Thu, 9 Nov 2000 16:52:17 +0000 (16:52 +0000)
Thu Nov  9 11:23:22 2000  Jonathan Blandford  <jrb@redhat.com>

* gtk/gtktreemodel.h (struct _GtkTreeIter): added more fields to
allow more interesting iterators.  Also, made the lifecycle of
iterators more explicit.

* gtk/gtktreemodelsort.[ch]: New model for sorting.

* gtk/gtk-boxed.defs (GtkTreeIter, GtkTreePath): Added two boxed
types.

25 files changed:
ChangeLog
ChangeLog.pre-2-0
ChangeLog.pre-2-10
ChangeLog.pre-2-2
ChangeLog.pre-2-4
ChangeLog.pre-2-6
ChangeLog.pre-2-8
demos/gtk-demo/main.c
demos/testgtk/main.c
gtk/Makefile.am
gtk/gtk-boxed.defs
gtk/gtk.h
gtk/gtkliststore.c
gtk/gtktreemodel.c
gtk/gtktreemodel.h
gtk/gtktreemodelsort.c [new file with mode: 0644]
gtk/gtktreemodelsort.h [new file with mode: 0644]
gtk/gtktreeselection.c
gtk/gtktreeselection.h
gtk/gtktreestore.c
gtk/gtktreeview.c
gtk/gtktreeviewcolumn.c
gtk/gtktreeviewcolumn.h
gtk/treestoretest.c
tests/treestoretest.c

index 58501223ea3be7c2be274843009e8d5999c5d736..e19d8625c380f622ba2a87df38422bc22e18346d 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+Thu Nov  9 11:23:22 2000  Jonathan Blandford  <jrb@redhat.com>
+
+       * gtk/gtktreemodel.h (struct _GtkTreeIter): added more fields to
+       allow more interesting iterators.  Also, made the lifecycle of
+       iterators more explicit.
+
+       * gtk/gtktreemodelsort.[ch]: New model for sorting.
+
+       * gtk/gtk-boxed.defs (GtkTreeIter, GtkTreePath): Added two boxed
+       types.
+
 2000-11-09  Alexander Larsson  <alexl@redhat.com>
 
        * demos/testgtk/menus.c:
index 58501223ea3be7c2be274843009e8d5999c5d736..e19d8625c380f622ba2a87df38422bc22e18346d 100644 (file)
@@ -1,3 +1,14 @@
+Thu Nov  9 11:23:22 2000  Jonathan Blandford  <jrb@redhat.com>
+
+       * gtk/gtktreemodel.h (struct _GtkTreeIter): added more fields to
+       allow more interesting iterators.  Also, made the lifecycle of
+       iterators more explicit.
+
+       * gtk/gtktreemodelsort.[ch]: New model for sorting.
+
+       * gtk/gtk-boxed.defs (GtkTreeIter, GtkTreePath): Added two boxed
+       types.
+
 2000-11-09  Alexander Larsson  <alexl@redhat.com>
 
        * demos/testgtk/menus.c:
index 58501223ea3be7c2be274843009e8d5999c5d736..e19d8625c380f622ba2a87df38422bc22e18346d 100644 (file)
@@ -1,3 +1,14 @@
+Thu Nov  9 11:23:22 2000  Jonathan Blandford  <jrb@redhat.com>
+
+       * gtk/gtktreemodel.h (struct _GtkTreeIter): added more fields to
+       allow more interesting iterators.  Also, made the lifecycle of
+       iterators more explicit.
+
+       * gtk/gtktreemodelsort.[ch]: New model for sorting.
+
+       * gtk/gtk-boxed.defs (GtkTreeIter, GtkTreePath): Added two boxed
+       types.
+
 2000-11-09  Alexander Larsson  <alexl@redhat.com>
 
        * demos/testgtk/menus.c:
index 58501223ea3be7c2be274843009e8d5999c5d736..e19d8625c380f622ba2a87df38422bc22e18346d 100644 (file)
@@ -1,3 +1,14 @@
+Thu Nov  9 11:23:22 2000  Jonathan Blandford  <jrb@redhat.com>
+
+       * gtk/gtktreemodel.h (struct _GtkTreeIter): added more fields to
+       allow more interesting iterators.  Also, made the lifecycle of
+       iterators more explicit.
+
+       * gtk/gtktreemodelsort.[ch]: New model for sorting.
+
+       * gtk/gtk-boxed.defs (GtkTreeIter, GtkTreePath): Added two boxed
+       types.
+
 2000-11-09  Alexander Larsson  <alexl@redhat.com>
 
        * demos/testgtk/menus.c:
index 58501223ea3be7c2be274843009e8d5999c5d736..e19d8625c380f622ba2a87df38422bc22e18346d 100644 (file)
@@ -1,3 +1,14 @@
+Thu Nov  9 11:23:22 2000  Jonathan Blandford  <jrb@redhat.com>
+
+       * gtk/gtktreemodel.h (struct _GtkTreeIter): added more fields to
+       allow more interesting iterators.  Also, made the lifecycle of
+       iterators more explicit.
+
+       * gtk/gtktreemodelsort.[ch]: New model for sorting.
+
+       * gtk/gtk-boxed.defs (GtkTreeIter, GtkTreePath): Added two boxed
+       types.
+
 2000-11-09  Alexander Larsson  <alexl@redhat.com>
 
        * demos/testgtk/menus.c:
index 58501223ea3be7c2be274843009e8d5999c5d736..e19d8625c380f622ba2a87df38422bc22e18346d 100644 (file)
@@ -1,3 +1,14 @@
+Thu Nov  9 11:23:22 2000  Jonathan Blandford  <jrb@redhat.com>
+
+       * gtk/gtktreemodel.h (struct _GtkTreeIter): added more fields to
+       allow more interesting iterators.  Also, made the lifecycle of
+       iterators more explicit.
+
+       * gtk/gtktreemodelsort.[ch]: New model for sorting.
+
+       * gtk/gtk-boxed.defs (GtkTreeIter, GtkTreePath): Added two boxed
+       types.
+
 2000-11-09  Alexander Larsson  <alexl@redhat.com>
 
        * demos/testgtk/menus.c:
index 58501223ea3be7c2be274843009e8d5999c5d736..e19d8625c380f622ba2a87df38422bc22e18346d 100644 (file)
@@ -1,3 +1,14 @@
+Thu Nov  9 11:23:22 2000  Jonathan Blandford  <jrb@redhat.com>
+
+       * gtk/gtktreemodel.h (struct _GtkTreeIter): added more fields to
+       allow more interesting iterators.  Also, made the lifecycle of
+       iterators more explicit.
+
+       * gtk/gtktreemodelsort.[ch]: New model for sorting.
+
+       * gtk/gtk-boxed.defs (GtkTreeIter, GtkTreePath): Added two boxed
+       types.
+
 2000-11-09  Alexander Larsson  <alexl@redhat.com>
 
        * demos/testgtk/menus.c:
index 656aeec4cc51cef3c8f99314b675f7135a6c84a4..baa906d0aca9eec48bdd66feb70d6a42f5cbf407 100644 (file)
@@ -242,7 +242,7 @@ selection_cb (GtkTreeSelection *selection,
   GtkTreeIter iter;
   GValue value = {0, };
 
-  if (! gtk_tree_selection_get_selected (selection, &iter))
+  if (! gtk_tree_selection_get_selected (selection, NULL, &iter))
     return;
 
   gtk_tree_model_get_value (model, &iter,
index 656aeec4cc51cef3c8f99314b675f7135a6c84a4..baa906d0aca9eec48bdd66feb70d6a42f5cbf407 100644 (file)
@@ -242,7 +242,7 @@ selection_cb (GtkTreeSelection *selection,
   GtkTreeIter iter;
   GValue value = {0, };
 
-  if (! gtk_tree_selection_get_selected (selection, &iter))
+  if (! gtk_tree_selection_get_selected (selection, NULL, &iter))
     return;
 
   gtk_tree_model_get_value (model, &iter,
index f4eaa8925b08aad61c292f44e105f9c8e902edae..e05b165c066b0c4b7cec3121bea2386e08261704 100644 (file)
@@ -171,6 +171,7 @@ gtk_public_h_sources = @STRIP_BEGIN@ \
        gtktree.h               \
        gtktreeitem.h           \
        gtktreemodel.h          \
+       gtktreemodelsort.h      \
        gtktreeselection.h      \
        gtktreestore.h          \
        gtktreeview.h           \
@@ -329,6 +330,7 @@ gtk_c_sources = @STRIP_BEGIN@   \
        gtktreeitem.c           \
        gtktreedatalist.c       \
        gtktreemodel.c          \
+       gtktreemodelsort.c      \
        gtktreeselection.c      \
        gtktreestore.c          \
        gtktreeview.c           \
index 27a3e873343f9a068ba96b8f8840409f04344167..b21c10498dd9c85b07eb97850107330e3cd6a700 100644 (file)
   gtk_text_iter_copy
   gtk_text_iter_free)
 
+;; TreeView
+(define-boxed GtkTreeIter
+  gtk_tree_iter_copy
+  gtk_tree_iter_free)
+
+(define-boxed GtkTreePath
+  gtk_tree_path_copy
+  gtk_tree_path_free)
+
 ;; Alignment
 
 (define-object GtkAlignment (GtkBin))
index ff27fb08cc4f88ea3d03fc663a9bc9aab6924e6f..a7b3e8818caedd6561926ddb0143d097d12d0719 100644 (file)
--- a/gtk/gtk.h
+++ b/gtk/gtk.h
 #include <gtk/gtktree.h>
 #include <gtk/gtktreeitem.h>
 #include <gtk/gtktreemodel.h>
+#include <gtk/gtktreemodelsort.h>
 #include <gtk/gtktreeselection.h>
 #include <gtk/gtktreestore.h>
 #include <gtk/gtktreeview.h>
index 032241cf3ae2d8bb437ebfacdd4dbfe254575b0d..c50974b4e393db276989fc56957a2596a90a67fe 100644 (file)
@@ -38,6 +38,7 @@ static guint list_store_signals[LAST_SIGNAL] = { 0 };
 static void         gtk_list_store_init            (GtkListStore      *list_store);
 static void         gtk_list_store_class_init      (GtkListStoreClass *class);
 static void         gtk_list_store_tree_model_init (GtkTreeModelIface *iface);
+static guint        gtk_list_store_get_flags       (GtkTreeModel      *tree_model);
 static gint         gtk_list_store_get_n_columns   (GtkTreeModel      *tree_model);
 static gboolean     gtk_list_store_get_iter        (GtkTreeModel      *tree_model,
                                                    GtkTreeIter       *iter,
@@ -152,6 +153,7 @@ gtk_list_store_class_init (GtkListStoreClass *class)
 static void
 gtk_list_store_tree_model_init (GtkTreeModelIface *iface)
 {
+  iface->get_flags = gtk_list_store_get_flags;
   iface->get_n_columns = gtk_list_store_get_n_columns;
   iface->get_iter = gtk_list_store_get_iter;
   iface->get_path = gtk_list_store_get_path;
@@ -168,7 +170,7 @@ static void
 gtk_list_store_init (GtkListStore *list_store)
 {
   list_store->root = NULL;
-  list_store->stamp = 1;
+  list_store->stamp = g_random_int ();
 }
 
 GtkListStore *
@@ -242,6 +244,14 @@ gtk_list_store_set_column_type (GtkListStore *list_store,
 }
 
 /* Fulfill the GtkTreeModel requirements */
+static guint
+gtk_list_store_get_flags (GtkTreeModel *tree_model)
+{
+  g_return_val_if_fail (GTK_IS_LIST_STORE (tree_model), 0);
+
+  return GTK_TREE_MODEL_ITERS_PERSIST;
+}
+
 static gint
 gtk_list_store_get_n_columns (GtkTreeModel *tree_model)
 {
@@ -350,6 +360,9 @@ static gint
 gtk_list_store_iter_n_children (GtkTreeModel *tree_model,
                                GtkTreeIter  *iter)
 {
+  if (iter == NULL)
+    return g_slist_length (G_SLIST (GTK_LIST_STORE (tree_model)->root));
+
   return 0;
 }
 
index af752dfd6d111be6daeef06ee2438e328f7e5f9c..ef3f05c659be1f99ef3e29ba223c3041f89ac5ab 100644 (file)
@@ -260,7 +260,7 @@ gtk_tree_path_free (GtkTreePath *path)
  * gtk_tree_path_copy:
  * @path: A #GtkTreePath.
  * 
- * Creates a new #GtkTreePath based upon @path.
+ * Creates a new #GtkTreePath as a copy of @path.
  * 
  * Return value: A new #GtkTreePath.
  **/
@@ -381,6 +381,69 @@ gtk_tree_path_down (GtkTreePath *path)
   gtk_tree_path_append_index (path, 0);
 }
 
+
+/**
+ * gtk_tree_iter_copy:
+ * @iter: A #GtkTreeIter.
+ * 
+ * Creates a dynamically allocated tree iterator as a copy of @iter.  This
+ * function is not intended for use in applications, because you can just copy
+ * the structs by value (<literal>GtkTreeIter new_iter = iter;</literal>).  You
+ * must free this iter with gtk_tree_iter_free ().
+ * 
+ * Return value: a newly allocated copy of @iter.
+ **/
+GtkTreeIter *
+gtk_tree_iter_copy (GtkTreeIter *iter)
+{
+  GtkTreeIter *retval;
+
+  g_return_val_if_fail (iter != NULL, NULL);
+
+  retval = g_new (GtkTreeIter, 1);
+  *retval = *iter;
+
+  return retval;
+}
+
+/**
+ * gtk_tree_iter_free:
+ * @iter: A dynamically allocated tree iterator.
+ * 
+ * Free an iterator that has been allocated on the heap.  This function is
+ * mainly used for language bindings.
+ **/
+void
+gtk_tree_iter_free (GtkTreeIter *iter)
+{
+  g_return_if_fail (iter != NULL);
+
+  g_free (iter);
+
+}
+
+/**
+ * gtk_tree_model_get_flags:
+ * @tree_model: A #GtkTreeModel.
+ * 
+ * Returns a list of flags supported by this interface.  The flags are a bitwise
+ * combination of #GtkTreeModelFlags.  It is expected that the flags supported
+ * do not change for an interface.
+ * 
+ * Return value: The flags supported by this interface.
+ **/
+guint
+gtk_tree_model_get_flags (GtkTreeModel *tree_model)
+{
+  g_return_val_if_fail (tree_model != NULL, 0);
+  g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), 0);
+
+  if (GTK_TREE_MODEL_GET_IFACE (tree_model)->get_flags)
+    return (GTK_TREE_MODEL_GET_IFACE (tree_model)->get_flags) (tree_model);
+
+  return 0;
+}
+
 /**
  * gtk_tree_model_get_n_columns:
  * @tree_model: A #GtkTreeModel.
@@ -399,6 +462,27 @@ gtk_tree_model_get_n_columns (GtkTreeModel *tree_model)
   return (* GTK_TREE_MODEL_GET_IFACE (tree_model)->get_n_columns) (tree_model);
 }
 
+/**
+ * gtk_tree_model_get_column_type:
+ * @tree_model: A #GtkTreeModel.
+ * @index: The column index.
+ * 
+ * Returns the type of the column.
+ * 
+ * Return value: The type of the column.
+ **/
+GType
+gtk_tree_model_get_column_type (GtkTreeModel *tree_model,
+                               gint          index)
+{
+  g_return_val_if_fail (tree_model != NULL, G_TYPE_INVALID);
+  g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), G_TYPE_INVALID);
+  g_return_val_if_fail (GTK_TREE_MODEL_GET_IFACE (tree_model)->get_column_type != NULL, G_TYPE_INVALID);
+  g_return_val_if_fail (index >= 0, G_TYPE_INVALID);
+
+  return (* GTK_TREE_MODEL_GET_IFACE (tree_model)->get_column_type) (tree_model, index);
+}
+
 /**
  * gtk_tree_model_get_iter:
  * @tree_model: A #GtkTreeModel.
@@ -564,9 +648,10 @@ gtk_tree_model_iter_has_child (GtkTreeModel *tree_model,
 /**
  * gtk_tree_model_iter_n_children:
  * @tree_model: A #GtkTreeModel.
- * @iter: The #GtkTreeIter.
+ * @iter: The #GtkTreeIter, or NULL.
  * 
- * Returns the number of children that @iter has.
+ * Returns the number of children that @iter has.  If @iter is NULL, then the
+ * number of toplevel nodes is returned.
  * 
  * Return value: The number of children of @iter.
  **/
@@ -576,7 +661,6 @@ gtk_tree_model_iter_n_children (GtkTreeModel *tree_model,
 {
   g_return_val_if_fail (tree_model != NULL, 0);
   g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), 0);
-  g_return_val_if_fail (iter != NULL, 0);
   g_return_val_if_fail (GTK_TREE_MODEL_GET_IFACE (tree_model)->iter_n_children != NULL, 0);
 
   return (* GTK_TREE_MODEL_GET_IFACE (tree_model)->iter_n_children) (tree_model, iter);
@@ -589,10 +673,11 @@ gtk_tree_model_iter_n_children (GtkTreeModel *tree_model,
  * @parent: The #GtkTreeIter to get the child from, or NULL.
  * @n: Then index of the desired child.
  * 
- * Sets @iter to be the child of @parent, using the given index.  The first index
- * is 0.  If the index is too big, or @parent has no children, @iter is set to an
- * invalid iterator and FALSE is returned.  @parent will remain a valid node after
- * this function has been called.  If @parent is NULL, then the root node is assumed.
+ * Sets @iter to be the child of @parent, using the given index.  The first
+ * index is 0.  If the index is too big, or @parent has no children, @iter is
+ * set to an invalid iterator and FALSE is returned.  @parent will remain a
+ * valid node after this function has been called.  If @parent is NULL, then the
+ * root node is assumed.
  * 
  * Return value: TRUE, if @parent has an nth child.
  **/
@@ -629,8 +714,51 @@ gtk_tree_model_iter_parent (GtkTreeModel *tree_model,
                            GtkTreeIter  *iter,
                            GtkTreeIter  *child)
 {
+  g_return_val_if_fail (tree_model != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), FALSE);
+  g_return_val_if_fail (iter != NULL, FALSE);
+  g_return_val_if_fail (child != NULL, FALSE);
   g_return_val_if_fail (GTK_TREE_MODEL_GET_IFACE (tree_model)->iter_parent != NULL, FALSE);
 
   return (* GTK_TREE_MODEL_GET_IFACE (tree_model)->iter_parent) (tree_model, iter, child);
 }
 
+/**
+ * gtk_tree_model_ref_iter:
+ * @tree_model: A #GtkTreeModel.
+ * @iter: The #GtkTreeIter.
+ * 
+ * Ref's the iter.  This is an optional method for models to implement.  To be
+ * more specific, models may ignore this call as it exists primarily for
+ * performance reasons.
+ **/
+void
+gtk_tree_model_ref_iter (GtkTreeModel *tree_model,
+                        GtkTreeIter  *iter)
+{
+  g_return_if_fail (tree_model != NULL);
+  g_return_if_fail (GTK_IS_TREE_MODEL (tree_model));
+
+  if (GTK_TREE_MODEL_GET_IFACE (tree_model)->ref_iter)
+    (* GTK_TREE_MODEL_GET_IFACE (tree_model)->ref_iter) (tree_model, iter);
+}
+
+/**
+ * gtk_tree_model_unref_iter:
+ * @tree_model: A #GtkTreeModel.
+ * @iter: The #GtkTreeIter.
+ * 
+ * Unref's the iter.  This is an optional method for models to implement.  To be
+ * more specific, models may ignore this call as it exists primarily for
+ * performance reasons.
+ **/
+void
+gtk_tree_model_unref_iter (GtkTreeModel *tree_model,
+                          GtkTreeIter  *iter)
+{
+  g_return_if_fail (tree_model != NULL);
+  g_return_if_fail (GTK_IS_TREE_MODEL (tree_model));
+
+  if (GTK_TREE_MODEL_GET_IFACE (tree_model)->unref_iter)
+    (* GTK_TREE_MODEL_GET_IFACE (tree_model)->unref_iter) (tree_model, iter);
+}
index fce77d60714afbb2f7e881a10850a0bc1ccc8905..ec5ba2b28c279b06198b882ceed73b0494c6124e 100644 (file)
@@ -37,10 +37,18 @@ typedef struct _GtkTreePath       GtkTreePath;
 typedef struct _GtkTreeModel      GtkTreeModel; /* Dummy typedef */
 typedef struct _GtkTreeModelIface GtkTreeModelIface;
 
+
+typedef enum
+{
+  GTK_TREE_MODEL_ITERS_PERSIST = 1 << 0
+} GtkTreeModelFlags;
+
 struct _GtkTreeIter
 {
   gint stamp;
   gpointer tree_node;
+  gpointer tree_node2;
+  gpointer tree_node3;
 };
 
 struct _GtkTreeModelIface
@@ -65,6 +73,7 @@ struct _GtkTreeModelIface
                                      GtkTreePath  *path);
 
   /* VTable - not signals */
+  guint        (* get_flags)       (GtkTreeModel *tree_model);   
   gint         (* get_n_columns)   (GtkTreeModel *tree_model);
   GType        (* get_column_type) (GtkTreeModel *tree_model,
                                    gint          index);
@@ -93,10 +102,14 @@ struct _GtkTreeModelIface
   gboolean     (* iter_parent)     (GtkTreeModel *tree_model,
                                    GtkTreeIter  *iter,
                                    GtkTreeIter  *child);
+  void         (* ref_iter)        (GtkTreeModel *tree_model,
+                                   GtkTreeIter  *iter);
+  void         (* unref_iter)      (GtkTreeModel *tree_model,
+                                   GtkTreeIter  *iter);
 };
 
 
-/* Path operations */
+/* GtkTreePath operations */
 GtkTreePath *gtk_tree_path_new              (void);
 GtkTreePath *gtk_tree_path_new_from_string  (gchar             *path);
 gchar       *gtk_tree_path_to_string        (GtkTreePath       *path);
@@ -117,9 +130,13 @@ gint         gtk_tree_path_up               (GtkTreePath       *path);
 void         gtk_tree_path_down             (GtkTreePath       *path);
 
 
+/* GtkTreeIter operations */
+GtkTreeIter *gtk_tree_iter_copy             (GtkTreeIter       *iter);
+void         gtk_tree_iter_free             (GtkTreeIter       *iter);
+
 /* GtkTreeModel stuff */
 GtkType      gtk_tree_model_get_type        (void) G_GNUC_CONST;
-
+guint        gtk_tree_model_get_flags       (GtkTreeModel      *tree_model);
 
 /* Column information */
 gint         gtk_tree_model_get_n_columns   (GtkTreeModel      *tree_model);
@@ -153,7 +170,10 @@ gboolean     gtk_tree_model_iter_nth_child  (GtkTreeModel      *tree_model,
 gboolean     gtk_tree_model_iter_parent     (GtkTreeModel      *tree_model,
                                             GtkTreeIter       *iter,
                                             GtkTreeIter       *child);
-
+void         gtk_tree_model_ref_iter        (GtkTreeModel      *tree_model,
+                                            GtkTreeIter       *iter);
+void         gtk_tree_model_unref_iter      (GtkTreeModel      *tree_model,
+                                            GtkTreeIter       *iter);
 
 #ifdef __cplusplus
 }
diff --git a/gtk/gtktreemodelsort.c b/gtk/gtktreemodelsort.c
new file mode 100644 (file)
index 0000000..608aeb8
--- /dev/null
@@ -0,0 +1,897 @@
+/* gtktreemodelsort.c
+ * Copyright (C) 2000  Red Hat, Inc.,  Jonathan Blandford <jrb@redhat.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "gtktreemodelsort.h"
+#include "gtksignal.h"
+
+enum {
+  CHANGED,
+  INSERTED,
+  CHILD_TOGGLED,
+  DELETED,
+  LAST_SIGNAL
+};
+
+typedef struct _SortElt SortElt;
+struct _SortElt
+{
+  GtkTreeIter iter;
+  SortElt *parent;
+  GArray *children;
+  gint ref;
+  gint offset;
+};
+
+static guint tree_model_sort_signals[LAST_SIGNAL] = { 0 };
+
+
+#define get_array(e,t) ((GArray *)((e)->parent?(e)->parent->children:GTK_TREE_MODEL_SORT(t)->root))
+
+static void         gtk_tree_model_sort_init            (GtkTreeModelSort      *tree_model_sort);
+static void         gtk_tree_model_sort_class_init      (GtkTreeModelSortClass *tree_model_sort_class);
+static void         gtk_tree_model_sort_tree_model_init (GtkTreeModelIface     *iface);
+static void         gtk_tree_model_sort_finalize        (GObject               *object);
+static void         gtk_tree_model_sort_changed         (GtkTreeModel          *model,
+                                                        GtkTreePath           *path,
+                                                        GtkTreeIter           *iter,
+                                                        gpointer               data);
+static void         gtk_tree_model_sort_inserted        (GtkTreeModel          *model,
+                                                        GtkTreePath           *path,
+                                                        GtkTreeIter           *iter,
+                                                        gpointer               data);
+static void         gtk_tree_model_sort_child_toggled   (GtkTreeModel          *model,
+                                                        GtkTreePath           *path,
+                                                        GtkTreeIter           *iter,
+                                                        gpointer               data);
+static void         gtk_tree_model_sort_deleted         (GtkTreeModel          *model,
+                                                        GtkTreePath           *path,
+                                                        gpointer               data);
+static gint         gtk_tree_model_sort_get_n_columns   (GtkTreeModel          *tree_model);
+static GType        gtk_tree_model_sort_get_column_type (GtkTreeModel          *tree_model,
+                                                        gint                   index);
+static gboolean     gtk_tree_model_sort_get_iter        (GtkTreeModel          *tree_model,
+                                                        GtkTreeIter           *iter,
+                                                        GtkTreePath           *path);
+static GtkTreePath *gtk_tree_model_sort_get_path        (GtkTreeModel          *tree_model,
+                                                        GtkTreeIter           *iter);
+static void         gtk_tree_model_sort_get_value       (GtkTreeModel          *tree_model,
+                                                        GtkTreeIter           *iter,
+                                                        gint                   column,
+                                                        GValue                *value);
+static gboolean     gtk_tree_model_sort_iter_next       (GtkTreeModel          *tree_model,
+                                                        GtkTreeIter           *iter);
+static gboolean     gtk_tree_model_sort_iter_children   (GtkTreeModel          *tree_model,
+                                                        GtkTreeIter           *iter,
+                                                        GtkTreeIter           *parent);
+static gboolean     gtk_tree_model_sort_iter_has_child  (GtkTreeModel          *tree_model,
+                                                        GtkTreeIter           *iter);
+static gint         gtk_tree_model_sort_iter_n_children (GtkTreeModel          *tree_model,
+                                                        GtkTreeIter           *iter);
+static gboolean     gtk_tree_model_sort_iter_nth_child  (GtkTreeModel          *tree_model,
+                                                        GtkTreeIter           *iter,
+                                                        GtkTreeIter           *parent,
+                                                        gint                   n);
+static gboolean     gtk_tree_model_sort_iter_parent     (GtkTreeModel          *tree_model,
+                                                        GtkTreeIter           *iter,
+                                                        GtkTreeIter           *child);
+static void         gtk_tree_model_sort_ref_iter        (GtkTreeModel          *tree_model,
+                                                        GtkTreeIter           *iter);
+static void         gtk_tree_model_sort_unref_iter      (GtkTreeModel          *tree_model,
+                                                        GtkTreeIter           *iter);
+
+/* Internal functions */
+static void         gtk_tree_model_sort_build_level     (GtkTreeModelSort      *tree_model_sort,
+                                                        SortElt               *place);
+static void         gtk_tree_model_sort_free_level      (GArray                *array);
+gint                g_value_string_compare_func         (const GValue          *a,
+                                                        const GValue          *b);
+gint                g_value_int_compare_func            (const GValue          *a,
+                                                        const GValue          *b);
+
+
+GtkType
+gtk_tree_model_sort_get_type (void)
+{
+  static GtkType tree_model_sort_type = 0;
+
+  if (!tree_model_sort_type)
+    {
+      static const GTypeInfo tree_model_sort_info =
+      {
+        sizeof (GtkTreeModelSortClass),
+       NULL,           /* base_init */
+       NULL,           /* base_finalize */
+        (GClassInitFunc) gtk_tree_model_sort_class_init,
+       NULL,           /* class_finalize */
+       NULL,           /* class_data */
+        sizeof (GtkTreeModelSort),
+       0,              /* n_preallocs */
+        (GInstanceInitFunc) gtk_tree_model_sort_init
+      };
+
+      static const GInterfaceInfo tree_model_info =
+      {
+       (GInterfaceInitFunc) gtk_tree_model_sort_tree_model_init,
+       NULL,
+       NULL
+      };
+
+      tree_model_sort_type = g_type_register_static (GTK_TYPE_OBJECT, "GtkTreeModelSort", &tree_model_sort_info, 0);
+      g_type_add_interface_static (tree_model_sort_type,
+                                  GTK_TYPE_TREE_MODEL,
+                                  &tree_model_info);
+    }
+
+  return tree_model_sort_type;
+}
+
+static void
+gtk_tree_model_sort_class_init (GtkTreeModelSortClass *tree_model_sort_class)
+{
+  GObjectClass *object_class;
+
+  object_class = (GObjectClass *) tree_model_sort_class;
+
+  tree_model_sort_signals[CHANGED] =
+    gtk_signal_new ("changed",
+                    GTK_RUN_FIRST,
+                    GTK_CLASS_TYPE (object_class),
+                    GTK_SIGNAL_OFFSET (GtkTreeModelSortClass, changed),
+                    gtk_marshal_VOID__POINTER_POINTER,
+                    GTK_TYPE_NONE, 2,
+                   GTK_TYPE_POINTER,
+                   GTK_TYPE_POINTER);
+  tree_model_sort_signals[INSERTED] =
+    gtk_signal_new ("inserted",
+                    GTK_RUN_FIRST,
+                    GTK_CLASS_TYPE (object_class),
+                    GTK_SIGNAL_OFFSET (GtkTreeModelSortClass, inserted),
+                    gtk_marshal_VOID__POINTER_POINTER,
+                    GTK_TYPE_NONE, 2,
+                   GTK_TYPE_POINTER,
+                   GTK_TYPE_POINTER);
+  tree_model_sort_signals[CHILD_TOGGLED] =
+    gtk_signal_new ("child_toggled",
+                    GTK_RUN_FIRST,
+                    GTK_CLASS_TYPE (object_class),
+                    GTK_SIGNAL_OFFSET (GtkTreeModelSortClass, child_toggled),
+                    gtk_marshal_VOID__POINTER_POINTER,
+                    GTK_TYPE_NONE, 2,
+                   GTK_TYPE_POINTER,
+                   GTK_TYPE_POINTER);
+  tree_model_sort_signals[DELETED] =
+    gtk_signal_new ("deleted",
+                    GTK_RUN_FIRST,
+                    GTK_CLASS_TYPE (object_class),
+                    GTK_SIGNAL_OFFSET (GtkTreeModelSortClass, deleted),
+                    gtk_marshal_VOID__POINTER,
+                    GTK_TYPE_NONE, 1,
+                   GTK_TYPE_POINTER);
+
+  object_class->finalize = gtk_tree_model_sort_finalize;
+
+  gtk_object_class_add_signals (GTK_OBJECT_CLASS (object_class), tree_model_sort_signals, LAST_SIGNAL);
+}
+
+static void
+gtk_tree_model_sort_tree_model_init (GtkTreeModelIface *iface)
+{
+  iface->get_n_columns = gtk_tree_model_sort_get_n_columns;
+  iface->get_column_type = gtk_tree_model_sort_get_column_type;
+  iface->get_iter = gtk_tree_model_sort_get_iter;
+  iface->get_path = gtk_tree_model_sort_get_path;
+  iface->get_value = gtk_tree_model_sort_get_value;
+  iface->iter_next = gtk_tree_model_sort_iter_next;
+  iface->iter_children = gtk_tree_model_sort_iter_children;
+  iface->iter_has_child = gtk_tree_model_sort_iter_has_child;
+  iface->iter_n_children = gtk_tree_model_sort_iter_n_children;
+  iface->iter_nth_child = gtk_tree_model_sort_iter_nth_child;
+  iface->iter_parent = gtk_tree_model_sort_iter_parent;
+  iface->ref_iter = gtk_tree_model_sort_ref_iter;
+  iface->unref_iter = gtk_tree_model_sort_unref_iter;
+}
+
+static void
+gtk_tree_model_sort_init (GtkTreeModelSort *tree_model_sort)
+{
+  tree_model_sort->stamp = g_random_int ();
+}
+
+GtkTreeModel *
+gtk_tree_model_sort_new (void)
+{
+  return GTK_TREE_MODEL (gtk_type_new (gtk_tree_model_sort_get_type ()));
+}
+
+GtkTreeModel *
+gtk_tree_model_sort_new_with_model (GtkTreeModel      *model,
+                                   GValueCompareFunc *func,
+                                   gint               sort_col)
+{
+  GtkTreeModel *retval;
+
+  retval = gtk_tree_model_sort_new ();
+  gtk_tree_model_sort_set_model (GTK_TREE_MODEL_SORT (retval), model);
+
+  GTK_TREE_MODEL_SORT (retval)->func = func;
+  GTK_TREE_MODEL_SORT (retval)->sort_col = sort_col;
+  return retval;
+}
+
+/**
+ * gtk_tree_model_sort_set_model:
+ * @tree_model_sort: The #GtkTreeModelSort.
+ * @model: A #GtkTreeModel, or NULL.
+ * 
+ * Sets the model of @tree_model_sort to be @model.  If @model is NULL, then the
+ * old model is unset.
+ **/
+void
+gtk_tree_model_sort_set_model (GtkTreeModelSort *tree_model_sort,
+                              GtkTreeModel     *model)
+{
+  g_return_if_fail (tree_model_sort != NULL);
+  g_return_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model_sort));
+
+  if (model)
+    g_object_ref (G_OBJECT (model));
+
+  if (tree_model_sort->model)
+    {
+      gtk_signal_disconnect_by_func (GTK_OBJECT (tree_model_sort->model),
+                                    gtk_tree_model_sort_changed,
+                                    tree_model_sort);
+      gtk_signal_disconnect_by_func (GTK_OBJECT (tree_model_sort->model),
+                                    gtk_tree_model_sort_inserted,
+                                    tree_model_sort);
+      gtk_signal_disconnect_by_func (GTK_OBJECT (tree_model_sort->model),
+                                    gtk_tree_model_sort_child_toggled,
+                                    tree_model_sort);
+      gtk_signal_disconnect_by_func (GTK_OBJECT (tree_model_sort->model),
+                                    gtk_tree_model_sort_deleted,
+                                    tree_model_sort);
+
+      g_object_unref (G_OBJECT (tree_model_sort->model));
+    }
+
+  tree_model_sort->model = model;
+
+  if (model)
+    {
+      gtk_signal_connect (GTK_OBJECT (model),
+                         "changed",
+                         gtk_tree_model_sort_changed,
+                         tree_model_sort);
+      gtk_signal_connect (GTK_OBJECT (model),
+                         "inserted",
+                         gtk_tree_model_sort_inserted,
+                         tree_model_sort);
+      gtk_signal_connect (GTK_OBJECT (model),
+                         "child_toggled",
+                         gtk_tree_model_sort_child_toggled,
+                         tree_model_sort);
+      gtk_signal_connect (GTK_OBJECT (model),
+                         "deleted",
+                         gtk_tree_model_sort_deleted,
+                         tree_model_sort);
+
+      tree_model_sort->flags = gtk_tree_model_get_flags (model);
+    }
+}
+
+/**
+ * gtk_tree_model_sort_convert_path:
+ * @tree_model_sort: The #GtkTreeModelSort.
+ * @path: A #GtkTreePath, relative to the @tree_model_sort 's model.
+ * 
+ * Converts the @path to a new path, relative to the sorted position.  In other
+ * words, the value found in the @tree_model_sort ->model at the @path, is
+ * identical to that found in the @tree_model_sort and the return value.
+ * 
+ * Return value: A new path, or NULL if @path does not exist in @tree_model_sort
+ * ->model.
+ **/
+GtkTreePath *
+gtk_tree_model_sort_convert_path (GtkTreeModelSort *tree_model_sort,
+                                 GtkTreePath      *path)
+{
+  GtkTreePath *retval;
+  GArray *array;
+  gint *indices;
+  gint i = 0;
+
+  if (tree_model_sort->root == NULL)
+    gtk_tree_model_sort_build_level (tree_model_sort, NULL);
+
+  retval = gtk_tree_path_new ();
+  array = (GArray *) tree_model_sort->root;
+  indices = gtk_tree_path_get_indices (path);
+
+  do
+    {
+      SortElt *elt;
+      gboolean found = FALSE;
+      gint j;
+
+      if ((array->len < indices[i]) || (array == NULL))
+       {
+         gtk_tree_path_free (path);
+         return NULL;
+       }
+
+      elt = (SortElt *) array->data;
+      for (j = 0; j < array->len; j++, elt++)
+       {
+         if (elt->offset == indices[i])
+           {
+             found = TRUE;
+             break;
+           }
+       }
+      if (! found)
+       {
+         gtk_tree_path_free (path);
+         return NULL;
+       }
+
+      gtk_tree_path_prepend_index (retval, j);
+      if (elt->children == NULL)
+       gtk_tree_model_sort_build_level (tree_model_sort, elt);
+      i++;
+    }
+  while (i < gtk_tree_path_get_depth (path));
+
+  return retval;
+}
+
+static void
+gtk_tree_model_sort_finalize (GObject *object)
+{
+  GtkTreeModelSort *tree_model_sort = (GtkTreeModelSort *) object;
+
+  if (tree_model_sort->root)
+    gtk_tree_model_sort_free_level (tree_model_sort->root);
+
+  g_object_unref (G_OBJECT (tree_model_sort->model));
+}
+
+static void
+gtk_tree_model_sort_changed (GtkTreeModel *model,
+                            GtkTreePath  *path,
+                            GtkTreeIter  *iter,
+                            gpointer      data)
+{
+  GtkTreeModelSort *tree_model_sort = GTK_TREE_MODEL_SORT (data);
+  GtkTreePath *local_path;
+  GtkTreeIter local_iter;
+
+  g_return_if_fail (path != NULL || iter != NULL);
+
+  if (path == NULL)
+    path = gtk_tree_model_get_path (model, iter);
+
+  local_path = gtk_tree_model_sort_convert_path (tree_model_sort, path);
+  gtk_tree_model_get_iter (GTK_TREE_MODEL (data), &local_iter, local_path);
+  gtk_signal_emit_by_name (GTK_OBJECT (data),
+                          "changed",
+                          local_path,
+                          &local_iter);
+  gtk_tree_path_free (local_path);
+}
+
+#if 0
+static void
+gtk_tree_model_sort_insert_value (GtkTreeModelSort *sort,
+                                 GtkTreeIter      *old_iter,
+                                 GtkTreePath      *path)
+{
+  GtkTreePath *parent_path;
+  GArray *array;
+  GtkTreeIter iter;
+  SortElt new_elt;
+  SortElt *tmp_elt;
+  gint high, low, middle;
+  GValueCompareFunc *func;
+  GValue tmp_value = {0, };
+  GValue old_value = {0, };
+
+  parent_path = gtk_tree_path_copy (path);
+  gtk_tree_path_up (parent_path);
+  gtk_tree_model_get_iter (GTK_TREE_MODEL (sort),
+                          &iter,
+                          parent_path);
+  gtk_tree_path_free (parent_path);
+  array = ((SortElt *) iter.tree_node)->children;
+
+  if (sort->func)
+    func = sort->func;
+  else
+    {
+      switch (gtk_tree_model_get_column_type (sort->model, sort->sort_col))
+       {
+       case G_TYPE_STRING:
+         func = &g_value_string_compare_func;
+         break;
+       case G_TYPE_INT:
+         func = &g_value_int_compare_func;
+         break;
+       default:
+         g_warning ("No comparison function for row %d\n", sort->sort_col);
+         return;
+       }
+    }
+
+  new_elt.iter = iter;
+  new_elt.ref = 0;
+  new_elt.parent = ((SortElt *) iter.tree_node);
+  new_elt.children = NULL;
+
+  last = 0;
+  j = array->len/2;
+  while (1)
+    {
+      gint cmp;
+      tmp_elt = &(g_array_index (array, SortElt, j));
+      gtk_tree_model_get_value (sort->model, tmp_elt, sort->sort_col, &tmp_value);
+                               
+      cmp = ((func) (&tmp_value, value));
+      if (retval < 0)
+       ;
+      else if (retval == 0)
+       g_array_insert_vals
+       ;
+      else if (retval > 0)
+       ;
+    }
+}
+#endif
+
+static void
+gtk_tree_model_sort_inserted (GtkTreeModel *model,
+                             GtkTreePath  *path,
+                             GtkTreeIter  *iter,
+                             gpointer      data)
+{
+  GtkTreeModelSort *tree_model_sort = GTK_TREE_MODEL_SORT (data);
+  GtkTreePath *local_path;
+  GtkTreeIter local_iter;
+  GValue value;
+
+  g_return_if_fail (path != NULL || iter != NULL);
+
+  if (!(tree_model_sort->flags & GTK_TREE_MODEL_ITERS_PERSIST) &&
+      (tree_model_sort->root != NULL))
+    {
+      gtk_tree_model_sort_free_level ((GArray *)tree_model_sort->root);
+      tree_model_sort->root = NULL;
+    }
+
+  if (path == NULL)
+    path = gtk_tree_model_get_path (model, iter);
+
+  local_path = gtk_tree_model_sort_convert_path (tree_model_sort, path);
+  gtk_tree_model_get_iter (GTK_TREE_MODEL (data), &local_iter, local_path);
+  gtk_signal_emit_by_name (GTK_OBJECT (data),
+                          "inserted",
+                          local_path,
+                          &local_iter);
+  gtk_tree_path_free (local_path);
+}
+
+static void
+gtk_tree_model_sort_child_toggled (GtkTreeModel *model,
+                                  GtkTreePath  *path,
+                                  GtkTreeIter  *iter,
+                                  gpointer      data)
+{
+  GtkTreeModelSort *tree_model_sort = GTK_TREE_MODEL_SORT (data);
+  GtkTreePath *local_path;
+  GtkTreeIter local_iter;
+
+  g_return_if_fail (path != NULL || iter != NULL);
+
+  if (!(tree_model_sort->flags & GTK_TREE_MODEL_ITERS_PERSIST) &&
+      (tree_model_sort->root != NULL))
+    {
+      gtk_tree_model_sort_free_level ((GArray *)tree_model_sort->root);
+      tree_model_sort->root = NULL;
+    }
+
+  if (path == NULL)
+    path = gtk_tree_model_get_path (model, iter);
+
+  local_path = gtk_tree_model_sort_convert_path (tree_model_sort, path);
+  gtk_tree_model_get_iter (GTK_TREE_MODEL (data), &local_iter, local_path);
+  gtk_signal_emit_by_name (GTK_OBJECT (data),
+                          "child_toggled",
+                          local_path,
+                          &local_iter);
+  gtk_tree_path_free (local_path);
+}
+
+static void
+gtk_tree_model_sort_deleted (GtkTreeModel *model,
+                            GtkTreePath  *path,
+                            gpointer      data)
+{
+  GtkTreeModelSort *tree_model_sort = GTK_TREE_MODEL_SORT (data);
+  GtkTreePath *local_path;
+
+  g_return_if_fail (path != NULL);
+
+  if (!(tree_model_sort->flags & GTK_TREE_MODEL_ITERS_PERSIST) &&
+      (tree_model_sort->root != NULL))
+    {
+      gtk_tree_model_sort_free_level ((GArray *)tree_model_sort->root);
+      tree_model_sort->root = NULL;
+    }
+  local_path = gtk_tree_model_sort_convert_path (tree_model_sort, path);
+  tree_model_sort->stamp++;
+  gtk_signal_emit_by_name (GTK_OBJECT (data),
+                          "deleted",
+                          local_path);
+
+  gtk_tree_path_free (local_path);
+}
+
+static gint
+gtk_tree_model_sort_get_n_columns (GtkTreeModel *tree_model)
+{
+  g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model), 0);
+  g_return_val_if_fail (GTK_TREE_MODEL_SORT (tree_model)->model != NULL, 0);
+
+  return gtk_tree_model_get_n_columns (GTK_TREE_MODEL_SORT (tree_model)->model);
+}
+
+static GType
+gtk_tree_model_sort_get_column_type (GtkTreeModel *tree_model,
+                                    gint          index)
+{
+  g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model), G_TYPE_INVALID);
+  g_return_val_if_fail (GTK_TREE_MODEL_SORT (tree_model)->model != NULL, G_TYPE_INVALID);
+
+  return gtk_tree_model_get_column_type (GTK_TREE_MODEL_SORT (tree_model)->model, index);
+}
+
+static gboolean
+gtk_tree_model_sort_get_iter_helper (GtkTreeModelSort *tree_model_sort,
+                                    GArray       *array,
+                                    GtkTreeIter  *iter,
+                                    gint          depth,
+                                    GtkTreePath  *path)
+{
+  SortElt *elt;
+
+  if (array == NULL)
+    return FALSE;
+
+  if (gtk_tree_path_get_indices (path)[depth] > array->len)
+    return FALSE;
+
+  elt = & (g_array_index (array, SortElt, gtk_tree_path_get_indices (path)[depth]));
+
+  if (depth == gtk_tree_path_get_depth (path) - 1)
+    {
+      iter->stamp = tree_model_sort->stamp;
+      iter->tree_node = elt;
+      return TRUE;
+    }
+
+  if (elt->children != NULL)
+    return gtk_tree_model_sort_get_iter_helper (tree_model_sort,
+                                               elt->children,
+                                               iter,
+                                               depth + 1,
+                                               path);
+
+  if (gtk_tree_model_iter_has_child (tree_model_sort->model,
+                                    &(elt->iter)))
+
+    gtk_tree_model_sort_build_level (tree_model_sort, elt);
+
+  return gtk_tree_model_sort_get_iter_helper (tree_model_sort,
+                                             elt->children,
+                                             iter,
+                                             depth + 1,
+                                             path);
+}
+
+static gboolean
+gtk_tree_model_sort_get_iter (GtkTreeModel *tree_model,
+                             GtkTreeIter  *iter,
+                             GtkTreePath  *path)
+{
+  g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model), FALSE);
+  g_return_val_if_fail (GTK_TREE_MODEL_SORT (tree_model)->model != NULL, FALSE);
+
+  if (GTK_TREE_MODEL_SORT (tree_model)->root == NULL)
+    gtk_tree_model_sort_build_level (GTK_TREE_MODEL_SORT (tree_model), NULL);
+
+  return gtk_tree_model_sort_get_iter_helper (GTK_TREE_MODEL_SORT (tree_model),
+                                             GTK_TREE_MODEL_SORT (tree_model)->root,
+                                             iter, 0, path);
+}
+
+static GtkTreePath *
+gtk_tree_model_sort_get_path (GtkTreeModel *tree_model,
+                             GtkTreeIter  *iter)
+{
+  g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model), NULL);
+  g_return_val_if_fail (GTK_TREE_MODEL_SORT (tree_model)->model != NULL, NULL);
+
+  return gtk_tree_model_get_path (GTK_TREE_MODEL_SORT (tree_model)->model, iter);
+}
+
+static void
+gtk_tree_model_sort_get_value (GtkTreeModel *tree_model,
+                              GtkTreeIter  *iter,
+                              gint          column,
+                              GValue        *value)
+{
+  SortElt *elt;
+
+  g_return_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model));
+  g_return_if_fail (GTK_TREE_MODEL_SORT (tree_model)->model != NULL);
+  g_return_if_fail (GTK_TREE_MODEL_SORT (tree_model)->stamp == iter->stamp);
+
+  elt = iter->tree_node;
+
+  gtk_tree_model_get_value (GTK_TREE_MODEL_SORT (tree_model)->model, (GtkTreeIter *)elt, column, value);
+}
+
+static gboolean
+gtk_tree_model_sort_iter_next (GtkTreeModel *tree_model,
+                              GtkTreeIter  *iter)
+{
+  GArray *array;
+  SortElt *elt;
+
+  g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model), FALSE);
+  g_return_val_if_fail (GTK_TREE_MODEL_SORT (tree_model)->model != NULL, FALSE);
+  g_return_val_if_fail (GTK_TREE_MODEL_SORT (tree_model)->stamp == iter->stamp, FALSE);
+
+  elt = iter->tree_node;
+  array = get_array (elt, tree_model);
+
+  if (elt - ((SortElt*) array->data) >=  array->len - 1)
+    {
+      iter->stamp = 0;
+      return FALSE;
+    }
+  iter->tree_node = elt+1;
+  return TRUE;
+}
+
+static gboolean
+gtk_tree_model_sort_iter_children (GtkTreeModel *tree_model,
+                                  GtkTreeIter  *iter,
+                                  GtkTreeIter  *parent)
+{
+  SortElt *elt;
+
+  g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model), FALSE);
+  g_return_val_if_fail (GTK_TREE_MODEL_SORT (tree_model)->model != NULL, FALSE);
+  if (parent)
+    g_return_val_if_fail (GTK_TREE_MODEL_SORT (tree_model)->stamp == parent->stamp, FALSE);
+
+  if (parent)
+    elt = parent->tree_node;
+  else
+    elt = (SortElt *) ((GArray *)GTK_TREE_MODEL_SORT (tree_model)->root)->data;
+
+  if (elt == NULL)
+    return FALSE;
+
+  if (elt->children == NULL &&
+      gtk_tree_model_iter_has_child (GTK_TREE_MODEL_SORT (tree_model)->model, (GtkTreeIter *)elt))
+    gtk_tree_model_sort_build_level (GTK_TREE_MODEL_SORT (tree_model), elt);
+
+  if (elt->children == NULL)
+    return FALSE;
+
+  iter->stamp = GTK_TREE_MODEL_SORT (tree_model)->stamp;
+  iter->tree_node = elt->children->data;
+
+  return TRUE;
+}
+
+static gboolean
+gtk_tree_model_sort_iter_has_child (GtkTreeModel *tree_model,
+                                   GtkTreeIter  *iter)
+{
+  SortElt *elt;
+
+  g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model), FALSE);
+  g_return_val_if_fail (GTK_TREE_MODEL_SORT (tree_model)->model != NULL, FALSE);
+  g_return_val_if_fail (GTK_TREE_MODEL_SORT (tree_model)->stamp == iter->stamp, FALSE);
+
+  elt = iter->tree_node;
+  if (elt->children)
+    return TRUE;
+
+  return gtk_tree_model_iter_has_child (GTK_TREE_MODEL_SORT (tree_model)->model, (GtkTreeIter *) elt);
+}
+
+static gint
+gtk_tree_model_sort_iter_n_children (GtkTreeModel *tree_model,
+                                    GtkTreeIter  *iter)
+{
+  SortElt *elt;
+
+  g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model), 0);
+  g_return_val_if_fail (GTK_TREE_MODEL_SORT (tree_model)->model != NULL, 0);
+  g_return_val_if_fail (GTK_TREE_MODEL_SORT (tree_model)->stamp == iter->stamp, 0);
+
+  elt = iter->tree_node;
+  if (elt->children)
+    return elt->children->len;
+
+  return gtk_tree_model_iter_n_children (GTK_TREE_MODEL_SORT (tree_model)->model, (GtkTreeIter *) elt);
+}
+
+
+static gboolean
+gtk_tree_model_sort_iter_nth_child (GtkTreeModel *tree_model,
+                                   GtkTreeIter  *iter,
+                                   GtkTreeIter  *parent,
+                                   gint          n)
+{
+  SortElt *elt;
+
+  g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model), FALSE);
+  g_return_val_if_fail (GTK_TREE_MODEL_SORT (tree_model)->model != NULL, FALSE);
+  if (parent)
+    g_return_val_if_fail (GTK_TREE_MODEL_SORT (tree_model)->stamp == parent->stamp, FALSE);
+
+  elt = iter->tree_node;
+
+
+  if (elt->children == NULL)
+    {
+      if (gtk_tree_model_iter_has_child (GTK_TREE_MODEL_SORT (tree_model)->model, (GtkTreeIter *)elt))
+       gtk_tree_model_sort_build_level (GTK_TREE_MODEL_SORT (tree_model), elt);
+      else
+       return FALSE;
+    }
+
+  if (elt->children == NULL)
+    return FALSE;
+
+  if (n >= elt->children->len)
+    return FALSE;
+
+  iter->stamp = GTK_TREE_MODEL_SORT (tree_model)->stamp;
+  iter->tree_node = &g_array_index (elt->children, SortElt, n);
+
+  return TRUE;
+}
+
+static gboolean
+gtk_tree_model_sort_iter_parent (GtkTreeModel *tree_model,
+                                GtkTreeIter  *iter,
+                                GtkTreeIter  *child)
+{
+  SortElt *elt;
+
+  g_return_val_if_fail (GTK_IS_TREE_MODEL_SORT (tree_model), FALSE);
+  g_return_val_if_fail (GTK_TREE_MODEL_SORT (tree_model)->model != NULL, FALSE);
+  g_return_val_if_fail (GTK_TREE_MODEL_SORT (tree_model)->stamp == child->stamp, FALSE);
+
+  elt = iter->tree_node;
+  if (elt->parent)
+    {
+      iter->stamp = GTK_TREE_MODEL_SORT (tree_model)->stamp;
+      iter->tree_node = elt->parent;
+
+      return TRUE;
+    }
+  return FALSE;
+}
+
+static void
+gtk_tree_model_sort_ref_iter (GtkTreeModel *tree_model,
+                             GtkTreeIter  *iter)
+{
+}
+
+static void
+gtk_tree_model_sort_unref_iter (GtkTreeModel *tree_model,
+                               GtkTreeIter  *iter)
+{
+
+}
+
+/* Internal functions */
+static void
+gtk_tree_model_sort_build_level (GtkTreeModelSort *tree_model_sort,
+                                SortElt          *place)
+{
+  gint n, i;
+  GArray *children;
+  GtkTreeIter *parent_iter = NULL;
+  GtkTreeIter iter;
+  SortElt elt;
+
+  if (place)
+    parent_iter = & (place->iter);
+
+      
+  n = gtk_tree_model_iter_n_children (tree_model_sort->model, parent_iter);
+
+  if (n == 0)
+    return;
+
+  children = g_array_sized_new (FALSE, FALSE, sizeof (SortElt), n);
+
+  if (place)
+    place->children = children;
+  else
+    tree_model_sort->root = children;
+
+  gtk_tree_model_iter_children (tree_model_sort->model,
+                               &iter,
+                               parent_iter);
+
+  i = 0;
+  do
+    {
+      elt.iter = iter;
+      elt.parent = place;
+      elt.children = NULL;
+      elt.ref = 0;
+      elt.offset = i;
+
+      g_array_append_vals (children, &elt, 1);
+      i++;
+    }
+  while (gtk_tree_model_iter_next (tree_model_sort->model, &iter));
+
+}
+
+static void
+gtk_tree_model_sort_free_level (GArray *array)
+{
+  gint i;
+
+  for (i = 0; i < array->len; i++)
+    {
+      SortElt *elt;
+
+      elt = &g_array_index (array, SortElt, i);
+      if (elt->children)
+       gtk_tree_model_sort_free_level (array);
+    }
+
+  g_array_free (array, TRUE);
+}
+
+gint
+g_value_string_compare_func (const GValue *a,
+                            const GValue *b)
+{
+  return strcmp (g_value_get_string (a),
+                g_value_get_string (b));
+}
+
+gint
+g_value_int_compare_func (const GValue *a,
+                         const GValue *b)
+{
+  return g_value_get_int (a) < g_value_get_int (b);
+}
diff --git a/gtk/gtktreemodelsort.h b/gtk/gtktreemodelsort.h
new file mode 100644 (file)
index 0000000..01366e6
--- /dev/null
@@ -0,0 +1,94 @@
+/* gtktreemodelsort.h
+ * Copyright (C) 2000  Red Hat, Inc.,  Jonathan Blandford <jrb@redhat.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __GTK_TREE_MODEL_SORT_H__
+#define __GTK_TREE_MODEL_SORT_H__
+
+#include <gtk/gtktreemodel.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#define GTK_TYPE_TREE_MODEL_SORT                       (gtk_tree_model_sort_get_type ())
+#define GTK_TREE_MODEL_SORT(obj)                       (GTK_CHECK_CAST ((obj), GTK_TYPE_TREE_MODEL_SORT, GtkTreeModelSort))
+#define GTK_TREE_MODEL_SORT_CLASS(klass)               (GTK_CHECK_CLASS_CAST ((klass), GTK_TYPE_TREE_MODEL_SORT, GtkTreeModelSortClass))
+#define GTK_IS_TREE_MODEL_SORT(obj)                    (GTK_CHECK_TYPE ((obj), GTK_TYPE_TREE_MODEL_SORT))
+#define GTK_IS_TREE_MODEL_SORT_CLASS(klass)            (GTK_CHECK_CLASS_TYPE ((obj), GTK_TYPE_TREE_MODEL_SORT))
+
+typedef struct _GtkTreeModelSort       GtkTreeModelSort;
+typedef struct _GtkTreeModelSortClass  GtkTreeModelSortClass;
+
+typedef gint (* GValueCompareFunc) (const GValue *a,
+                                   const GValue *b);
+
+struct _GtkTreeModelSort
+{
+  GtkObject parent;
+
+  /* < private > */
+  gpointer root;
+  gint stamp;
+  guint flags;
+  GtkTreeModel *model;
+  gint sort_col;
+  GValueCompareFunc *func;
+};
+
+struct _GtkTreeModelSortClass
+{
+  GtkObjectClass parent_class;
+
+  /* signals */
+  /* Will be moved into the GtkTreeModelIface eventually */
+  void (* changed)       (GtkTreeModel *tree_model,
+                         GtkTreePath  *path,
+                         GtkTreeIter  *iter);
+  void (* inserted)      (GtkTreeModel *tree_model,
+                         GtkTreePath  *path,
+                         GtkTreeIter  *iter);
+  void (* child_toggled) (GtkTreeModel *tree_model,
+                         GtkTreePath  *path,
+                         GtkTreeIter  *iter);
+  void (* deleted)       (GtkTreeModel *tree_model,
+                         GtkTreePath  *path);
+};
+
+
+GtkType       gtk_tree_model_sort_get_type       (void);
+GtkTreeModel *gtk_tree_model_sort_new            (void);
+GtkTreeModel *gtk_tree_model_sort_new_with_model (GtkTreeModel      *model,
+                                                 GValueCompareFunc *func,
+                                                 gint               sort_col);
+void          gtk_tree_model_sort_set_model      (GtkTreeModelSort  *tree_model_sort,
+                                                 GtkTreeModel      *model);
+void          gtk_tree_model_sort_set_sort_col   (GtkTreeModelSort  *tree_model_sort,
+                                                 gint               sort_col);
+void          gtk_tree_model_sort_set_compare    (GtkTreeModelSort  *tree_model_sort,
+                                                 GValueCompareFunc *func);
+void          gtk_tree_model_sort_resort         (GtkTreeModelSort  *tree_model_sort);
+GtkTreePath  *gtk_tree_model_sort_convert_path   (GtkTreeModelSort  *tree_model_sort,
+                                                 GtkTreePath       *path);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+
+#endif /* __GTK_TREE_MODEL_SORT_H__ */
index 414eae2bff5eae55063944acfcca092e81d90f44..706549ee3106d3df7c56f345b5e1dfada861a9e9 100644 (file)
@@ -241,17 +241,20 @@ gtk_tree_selection_get_user_data (GtkTreeSelection *selection)
 /**
  * gtk_tree_selection_get_selected:
  * @selection: A #GtkTreeSelection.
+ * @model: A pointer set to the #GtkTreeModel, or NULL.
  * @iter: The #GtkTreeIter, or NULL.
  * 
  * Sets @iter to the currently selected node if @selection is set to
  * #GTK_TREE_SELECTION_SINGLE.  Otherwise, it uses the anchor.  @iter may be
- * NULL if you just want to test if @selection has any selected nodes.
+ * NULL if you just want to test if @selection has any selected nodes.  @model
+ * is filled with the current model as a convenience.
  * 
  * Return value: TRUE, if there is a selected node.
  **/
 gboolean
-gtk_tree_selection_get_selected (GtkTreeSelection *selection,
-                                GtkTreeIter      *iter)
+gtk_tree_selection_get_selected (GtkTreeSelection  *selection,
+                                GtkTreeModel     **model,
+                                GtkTreeIter       *iter)
 {
   GtkRBTree *tree;
   GtkRBNode *node;
@@ -274,9 +277,11 @@ gtk_tree_selection_get_selected (GtkTreeSelection *selection,
       ! GTK_RBNODE_FLAG_SET (node, GTK_RBNODE_IS_SELECTED))
     /* We don't want to return the anchor if it isn't actually selected.
      */
-
       return FALSE;
 
+  if (model)
+    *model = selection->tree_view->priv->model;
+
   return gtk_tree_model_get_iter (selection->tree_view->priv->model,
                                  iter,
                                  selection->tree_view->priv->anchor);
index cafedf7dd8981c1c31cc7572c3536dea0e1f45f7..3f7201ec3fa77992210ae4cd90a5716e46468321 100644 (file)
@@ -79,6 +79,7 @@ gpointer         gtk_tree_selection_get_user_data       (GtkTreeSelection
 /* Only meaningful if GTK_TREE_SELECTION_SINGLE is set */
 /* Use selected_foreach for GTK_TREE_SELECTION_MULTI */
 gboolean         gtk_tree_selection_get_selected        (GtkTreeSelection            *selection,
+                                                        GtkTreeModel               **model,
                                                         GtkTreeIter                 *iter);
 
 /* FIXME: Get a more convenient get_selection function????  one returning GSList?? */
index 3454202ad43b444fbea861b37ee7d2396e5b38da..44befc800a22131474e91516120ce4b6d474d50a 100644 (file)
@@ -40,6 +40,7 @@ static guint tree_store_signals[LAST_SIGNAL] = { 0 };
 static void         gtk_tree_store_init            (GtkTreeStore      *tree_store);
 static void         gtk_tree_store_class_init      (GtkTreeStoreClass *tree_store_class);
 static void         gtk_tree_store_tree_model_init (GtkTreeModelIface *iface);
+static guint        gtk_tree_store_get_flags       (GtkTreeModel      *tree_model);
 static gint         gtk_tree_store_get_n_columns   (GtkTreeModel      *tree_model);
 static GtkTreePath *gtk_tree_store_get_path        (GtkTreeModel      *tree_model,
                                                    GtkTreeIter       *iter);
@@ -58,11 +59,11 @@ static gint         gtk_tree_store_iter_n_children (GtkTreeModel      *tree_mode
                                                    GtkTreeIter       *iter);
 static gboolean     gtk_tree_store_iter_nth_child  (GtkTreeModel      *tree_model,
                                                    GtkTreeIter       *iter,
-                                                   GtkTreeIter       *child,
+                                                   GtkTreeIter       *parent,
                                                    gint               n);
 static gboolean     gtk_tree_store_iter_parent     (GtkTreeModel      *tree_model,
                                                    GtkTreeIter       *iter,
-                                                   GtkTreeIter       *parent);
+                                                   GtkTreeIter       *child);
 
 
 GtkType
@@ -150,6 +151,7 @@ gtk_tree_store_class_init (GtkTreeStoreClass *tree_store_class)
 static void
 gtk_tree_store_tree_model_init (GtkTreeModelIface *iface)
 {
+  iface->get_flags = gtk_tree_store_get_flags;
   iface->get_n_columns = gtk_tree_store_get_n_columns;
   iface->get_path = gtk_tree_store_get_path;
   iface->get_value = gtk_tree_store_get_value;
@@ -165,7 +167,7 @@ static void
 gtk_tree_store_init (GtkTreeStore *tree_store)
 {
   tree_store->root = g_node_new (NULL);
-  tree_store->stamp = 1;
+  tree_store->stamp = g_random_int ();
 }
 
 GtkTreeStore *
@@ -242,10 +244,19 @@ gtk_tree_store_set_column_type (GtkTreeStore *tree_store,
  * it is not visible to the tree or to the user., and the path "1" refers to the
  * first child of GtkTreeStore::root.
  */
+
+
+static guint
+gtk_tree_store_get_flags (GtkTreeModel *tree_model)
+{
+  g_return_val_if_fail (GTK_IS_TREE_STORE (tree_model), 0);
+
+  return GTK_TREE_MODEL_ITERS_PERSIST;
+}
+
 static gint
 gtk_tree_store_get_n_columns (GtkTreeModel *tree_model)
 {
-  g_return_val_if_fail (tree_model != NULL, 0);
   g_return_val_if_fail (GTK_IS_TREE_STORE (tree_model), 0);
 
   return GTK_TREE_STORE (tree_model)->n_columns;
@@ -362,7 +373,10 @@ gtk_tree_store_iter_children (GtkTreeModel *tree_model,
                              GtkTreeIter  *parent)
 {
   iter->stamp = GTK_TREE_STORE (tree_model)->stamp;
-  iter->tree_node = G_NODE (parent->tree_node)->children;
+  if (parent)
+    iter->tree_node = G_NODE (parent->tree_node)->children;
+  else
+    iter->tree_node = G_NODE (GTK_TREE_STORE (tree_model)->root)->children;
 
   return iter->tree_node != NULL;
 }
@@ -388,10 +402,13 @@ gtk_tree_store_iter_n_children (GtkTreeModel *tree_model,
 
   g_return_val_if_fail (tree_model != NULL, 0);
   g_return_val_if_fail (GTK_IS_TREE_STORE (tree_model), 0);
-  g_return_val_if_fail (iter != NULL, 0);
-  g_return_val_if_fail (iter->stamp == GTK_TREE_STORE (tree_model)->stamp, 0);
+  if (iter)
+    g_return_val_if_fail (iter->stamp == GTK_TREE_STORE (tree_model)->stamp, 0);
 
-  node = G_NODE (iter->tree_node)->children;
+  if (iter == NULL)
+    node = G_NODE (GTK_TREE_STORE (tree_model)->root)->children;
+  else
+    node = G_NODE (iter->tree_node)->children;
   while (node)
     {
       i++;
index 837948610635c6ba814454cc4e4aa4d523658593..de3d504726545e37277cc5feb6bd3fc62920a2e1 100644 (file)
@@ -2037,6 +2037,8 @@ gtk_tree_view_inserted (GtkTreeModel *model,
        }
     }
 
+  /* ref the node */
+  gtk_tree_model_ref_iter (tree_view->priv->model, iter);
   max_height = gtk_tree_view_insert_iter_height (tree_view,
                                                 tree,
                                                 iter,
@@ -2245,6 +2247,8 @@ gtk_tree_view_build_tree (GtkTreeView *tree_view,
                                                       tree,
                                                       iter,
                                                       depth);
+
+      gtk_tree_model_ref_iter (tree_view->priv->model, iter);
       temp = _gtk_rbtree_insert_after (tree, temp, max_height);
       if (recurse)
        {
index 6c51f4355d48f777573aedb2435526e27315b5dd..2ecefdb5b0a2e8c9d8a8c9eceae5f31f74c73b8c 100644 (file)
@@ -145,12 +145,12 @@ gtk_real_tree_column_clicked (GtkTreeViewColumn *tree_column)
  * 
  * Return value: A newly created #GtkTreeViewColumn.
  **/
-GtkObject *
+GtkTreeViewColumn *
 gtk_tree_view_column_new (void)
 {
-  GtkObject *retval;
+  GtkTreeViewColumn *retval;
 
-  retval = GTK_OBJECT (gtk_type_new (GTK_TYPE_TREE_COLUMN));
+  retval = GTK_TREE_VIEW_COLUMN (gtk_type_new (GTK_TYPE_TREE_COLUMN));
 
   return retval;
 }
@@ -168,22 +168,21 @@ gtk_tree_view_column_new (void)
  * 
  * Return value: A newly created #GtkTreeViewColumn.
  **/
-GtkObject *
+GtkTreeViewColumn *
 gtk_tree_view_column_new_with_attributes (gchar           *title,
                                          GtkCellRenderer *cell,
                                          ...)
 {
-  GtkObject *retval;
+  GtkTreeViewColumn *retval;
   va_list args;
 
   retval = gtk_tree_view_column_new ();
 
-  gtk_tree_view_column_set_title (GTK_TREE_VIEW_COLUMN (retval), title);
-  gtk_tree_view_column_set_cell_renderer (GTK_TREE_VIEW_COLUMN (retval), cell);
+  gtk_tree_view_column_set_title (retval, title);
+  gtk_tree_view_column_set_cell_renderer (retval, cell);
 
   va_start (args, cell);
-  gtk_tree_view_column_set_attributesv (GTK_TREE_VIEW_COLUMN (retval),
-                                       args);
+  gtk_tree_view_column_set_attributesv (retval, args);
   va_end (args);
 
   return retval;
index 091ff07154c4aea87a95a059a8b59b7f2961827b..148c488ac81c2d8f2d1280c640452e34d95ce280 100644 (file)
@@ -82,51 +82,53 @@ struct _GtkTreeViewColumnClass
 };
 
 
-GtkType          gtk_tree_view_column_get_type            (void);
-GtkObject       *gtk_tree_view_column_new                 (void);
-GtkObject       *gtk_tree_view_column_new_with_attributes (gchar                 *title,
-                                                          GtkCellRenderer       *cell,
-                                                          ...);
-void             gtk_tree_view_column_set_cell_renderer   (GtkTreeViewColumn     *tree_column,
-                                                          GtkCellRenderer       *cell);
-void             gtk_tree_view_column_add_attribute       (GtkTreeViewColumn     *tree_column,
-                                                          gchar                 *attribute,
-                                                          gint                   column);
-void             gtk_tree_view_column_set_attributes      (GtkTreeViewColumn     *tree_column,
-                                                          ...);
-void             gtk_tree_view_column_set_cell_data       (GtkTreeViewColumn     *tree_column,
-                                                          GtkTreeModel          *tree_model,
-                                                          GtkTreeIter           *iter);
-void             gtk_tree_view_column_set_visible         (GtkTreeViewColumn     *tree_column,
-                                                          gboolean               visible);
-gboolean         gtk_tree_view_column_get_visible         (GtkTreeViewColumn     *tree_column);
-void             gtk_tree_view_column_set_col_type        (GtkTreeViewColumn     *tree_column,
-                                                          GtkTreeViewColumnType  type);
-gint             gtk_tree_view_column_get_col_type        (GtkTreeViewColumn     *tree_column);
-gint             gtk_tree_view_column_get_size            (GtkTreeViewColumn     *tree_column);
-void             gtk_tree_view_column_set_size            (GtkTreeViewColumn     *tree_column,
-                                                          gint                   size);
-void             gtk_tree_view_column_set_min_width       (GtkTreeViewColumn     *tree_column,
-                                                          gint                   min_width);
-gint             gtk_tree_view_column_get_min_width       (GtkTreeViewColumn     *tree_column);
-void             gtk_tree_view_column_set_max_width       (GtkTreeViewColumn     *tree_column,
-                                                          gint                   max_width);
-gint             gtk_tree_view_column_get_max_width       (GtkTreeViewColumn     *tree_column);
+GtkType            gtk_tree_view_column_get_type            (void);
+GtkTreeViewColumn *gtk_tree_view_column_new                 (void);
+GtkTreeViewColumn *gtk_tree_view_column_new_with_attributes (gchar                 *title,
+                                                            GtkCellRenderer       *cell,
+                                                            ...);
+void               gtk_tree_view_column_set_cell_renderer   (GtkTreeViewColumn     *tree_column,
+                                                            GtkCellRenderer       *cell);
+void               gtk_tree_view_column_add_attribute       (GtkTreeViewColumn     *tree_column,
+                                                            gchar                 *attribute,
+                                                            gint                   column);
+void               gtk_tree_view_column_set_attributes      (GtkTreeViewColumn     *tree_column,
+                                                            ...);
+void               gtk_tree_view_column_set_cell_data       (GtkTreeViewColumn     *tree_column,
+                                                            GtkTreeModel          *tree_model,
+                                                            GtkTreeIter           *iter);
+void               gtk_tree_view_column_set_visible         (GtkTreeViewColumn     *tree_column,
+                                                            gboolean               visible);
+gboolean           gtk_tree_view_column_get_visible         (GtkTreeViewColumn     *tree_column);
+void               gtk_tree_view_column_set_col_type        (GtkTreeViewColumn     *tree_column,
+                                                            GtkTreeViewColumnType  type);
+gint               gtk_tree_view_column_get_col_type        (GtkTreeViewColumn     *tree_column);
+gint               gtk_tree_view_column_get_size            (GtkTreeViewColumn     *tree_column);
+void               gtk_tree_view_column_set_size            (GtkTreeViewColumn     *tree_column,
+                                                            gint                   size);
+void               gtk_tree_view_column_set_min_width       (GtkTreeViewColumn     *tree_column,
+                                                            gint                   min_width);
+gint               gtk_tree_view_column_get_min_width       (GtkTreeViewColumn     *tree_column);
+void               gtk_tree_view_column_set_max_width       (GtkTreeViewColumn     *tree_column,
+                                                            gint                   max_width);
+gint               gtk_tree_view_column_get_max_width       (GtkTreeViewColumn     *tree_column);
+
 
 
 /* Options for manipulating the column headers
  */
-void             gtk_tree_view_column_set_title           (GtkTreeViewColumn     *tree_column,
-                                                          gchar                 *title);
-gchar           *gtk_tree_view_column_get_title           (GtkTreeViewColumn     *tree_column);
-void             gtk_tree_view_column_set_header_active   (GtkTreeViewColumn     *tree_column,
-                                                          gboolean               active);
-void             gtk_tree_view_column_set_widget          (GtkTreeViewColumn     *tree_column,
-                                                          GtkWidget             *widget);
-GtkWidget       *gtk_tree_view_column_get_widget          (GtkTreeViewColumn     *tree_column);
-void             gtk_tree_view_column_set_justification   (GtkTreeViewColumn     *tree_column,
-                                                          GtkJustification       justification);
-GtkJustification gtk_tree_view_column_get_justification   (GtkTreeViewColumn     *tree_column);
+void               gtk_tree_view_column_set_title           (GtkTreeViewColumn     *tree_column,
+                                                            gchar                 *title);
+gchar             *gtk_tree_view_column_get_title           (GtkTreeViewColumn     *tree_column);
+void               gtk_tree_view_column_set_header_active   (GtkTreeViewColumn     *tree_column,
+                                                            gboolean               active);
+void               gtk_tree_view_column_set_widget          (GtkTreeViewColumn     *tree_column,
+                                                            GtkWidget             *widget);
+GtkWidget         *gtk_tree_view_column_get_widget          (GtkTreeViewColumn     *tree_column);
+void               gtk_tree_view_column_set_justification   (GtkTreeViewColumn     *tree_column,
+                                                            GtkJustification       justification);
+GtkJustification   gtk_tree_view_column_get_justification   (GtkTreeViewColumn     *tree_column);
+
 
 
 #ifdef __cplusplus
index d1c311c836e17fcf0504a73390c78173cd760f5c..3835d9d17088a1a1baf379ab0cabe064d776314f 100644 (file)
@@ -7,8 +7,7 @@ static void
 selection_changed (GtkTreeSelection *selection,
                   GtkWidget        *button)
 {
-  if (gtk_tree_selection_get_selected (selection,
-                                      NULL))
+  if (gtk_tree_selection_get_selected (selection, NULL, NULL))
     gtk_widget_set_sensitive (button, TRUE);
   else
     gtk_widget_set_sensitive (button, FALSE);
@@ -31,6 +30,7 @@ iter_remove (GtkWidget *button, GtkTreeView *tree_view)
 {
   GtkTreeIter selected;
   if (gtk_tree_selection_get_selected (gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view)),
+                                      NULL,
                                       &selected))
     {
       gtk_tree_store_remove (model, &selected);
@@ -46,6 +46,7 @@ iter_insert (GtkWidget *button, GtkTreeView *tree_view)
 
   entry = gtk_object_get_user_data (GTK_OBJECT (button));
   if (gtk_tree_selection_get_selected (gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view)),
+                                      NULL,
                                       &selected))
     {
       gtk_tree_store_insert (model,
@@ -71,6 +72,7 @@ iter_insert_before  (GtkWidget *button, GtkTreeView *tree_view)
   GtkTreeIter selected;
 
   if (gtk_tree_selection_get_selected (gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view)),
+                                      NULL,
                                       &selected))
     {
       gtk_tree_store_insert_before (model,
@@ -96,6 +98,7 @@ iter_insert_after (GtkWidget *button, GtkTreeView *tree_view)
   GtkTreeIter selected;
 
   if (gtk_tree_selection_get_selected (gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view)),
+                                      NULL,
                                       &selected))
     {
       gtk_tree_store_insert_after (model,
@@ -121,6 +124,7 @@ iter_prepend (GtkWidget *button, GtkTreeView *tree_view)
   GtkTreeIter selected;
 
   if (gtk_tree_selection_get_selected (gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view)),
+                                      NULL,
                                       &selected))
     {
       gtk_tree_store_prepend (model,
@@ -144,6 +148,7 @@ iter_append (GtkWidget *button, GtkTreeView *tree_view)
   GtkTreeIter selected;
 
   if (gtk_tree_selection_get_selected (gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view)),
+                                      NULL,
                                       &selected))
     {
       gtk_tree_store_append (model, &iter, &selected);
@@ -159,13 +164,14 @@ iter_append (GtkWidget *button, GtkTreeView *tree_view)
 static void
 make_window ()
 {
+  GtkTreeModel *sort_model;
   GtkWidget *window;
   GtkWidget *vbox;
   GtkWidget *hbox, *entry;
   GtkWidget *button;
   GtkWidget *scrolled_window;
   GtkWidget *tree_view;
-  GtkObject *column;
+  GtkTreeViewColumn *column;
   GtkCellRenderer *cell;
   GtkObject *selection;
 
@@ -175,7 +181,9 @@ make_window ()
   gtk_container_set_border_width (GTK_CONTAINER (vbox), 8);
   gtk_window_set_default_size (GTK_WINDOW (window), 300, 350);
   scrolled_window = gtk_scrolled_window_new (NULL, NULL);
-  tree_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (model));
+  sort_model = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (model),
+                                                  NULL, 0);
+  tree_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (sort_model));
   selection = GTK_OBJECT (gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view)));
   gtk_tree_selection_set_type (GTK_TREE_SELECTION (selection), GTK_TREE_SELECTION_SINGLE);
 
@@ -237,7 +245,7 @@ make_window ()
   /* The selected column */
   cell = gtk_cell_renderer_text_new ();
   column = gtk_tree_view_column_new_with_attributes ("nodes", cell, "text", 0, NULL);
-  gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), GTK_TREE_VIEW_COLUMN (column));
+  gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), column);
 
   /* A few to start */
   iter_prepend (NULL, GTK_TREE_VIEW (tree_view));
@@ -254,7 +262,7 @@ main (int argc, char *argv[])
   gtk_init (&argc, &argv);
 
   model = gtk_tree_store_new_with_values (2, G_TYPE_STRING, G_TYPE_STRING);
-
+  
   make_window ();
   make_window ();
 
index d1c311c836e17fcf0504a73390c78173cd760f5c..3835d9d17088a1a1baf379ab0cabe064d776314f 100644 (file)
@@ -7,8 +7,7 @@ static void
 selection_changed (GtkTreeSelection *selection,
                   GtkWidget        *button)
 {
-  if (gtk_tree_selection_get_selected (selection,
-                                      NULL))
+  if (gtk_tree_selection_get_selected (selection, NULL, NULL))
     gtk_widget_set_sensitive (button, TRUE);
   else
     gtk_widget_set_sensitive (button, FALSE);
@@ -31,6 +30,7 @@ iter_remove (GtkWidget *button, GtkTreeView *tree_view)
 {
   GtkTreeIter selected;
   if (gtk_tree_selection_get_selected (gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view)),
+                                      NULL,
                                       &selected))
     {
       gtk_tree_store_remove (model, &selected);
@@ -46,6 +46,7 @@ iter_insert (GtkWidget *button, GtkTreeView *tree_view)
 
   entry = gtk_object_get_user_data (GTK_OBJECT (button));
   if (gtk_tree_selection_get_selected (gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view)),
+                                      NULL,
                                       &selected))
     {
       gtk_tree_store_insert (model,
@@ -71,6 +72,7 @@ iter_insert_before  (GtkWidget *button, GtkTreeView *tree_view)
   GtkTreeIter selected;
 
   if (gtk_tree_selection_get_selected (gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view)),
+                                      NULL,
                                       &selected))
     {
       gtk_tree_store_insert_before (model,
@@ -96,6 +98,7 @@ iter_insert_after (GtkWidget *button, GtkTreeView *tree_view)
   GtkTreeIter selected;
 
   if (gtk_tree_selection_get_selected (gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view)),
+                                      NULL,
                                       &selected))
     {
       gtk_tree_store_insert_after (model,
@@ -121,6 +124,7 @@ iter_prepend (GtkWidget *button, GtkTreeView *tree_view)
   GtkTreeIter selected;
 
   if (gtk_tree_selection_get_selected (gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view)),
+                                      NULL,
                                       &selected))
     {
       gtk_tree_store_prepend (model,
@@ -144,6 +148,7 @@ iter_append (GtkWidget *button, GtkTreeView *tree_view)
   GtkTreeIter selected;
 
   if (gtk_tree_selection_get_selected (gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view)),
+                                      NULL,
                                       &selected))
     {
       gtk_tree_store_append (model, &iter, &selected);
@@ -159,13 +164,14 @@ iter_append (GtkWidget *button, GtkTreeView *tree_view)
 static void
 make_window ()
 {
+  GtkTreeModel *sort_model;
   GtkWidget *window;
   GtkWidget *vbox;
   GtkWidget *hbox, *entry;
   GtkWidget *button;
   GtkWidget *scrolled_window;
   GtkWidget *tree_view;
-  GtkObject *column;
+  GtkTreeViewColumn *column;
   GtkCellRenderer *cell;
   GtkObject *selection;
 
@@ -175,7 +181,9 @@ make_window ()
   gtk_container_set_border_width (GTK_CONTAINER (vbox), 8);
   gtk_window_set_default_size (GTK_WINDOW (window), 300, 350);
   scrolled_window = gtk_scrolled_window_new (NULL, NULL);
-  tree_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (model));
+  sort_model = gtk_tree_model_sort_new_with_model (GTK_TREE_MODEL (model),
+                                                  NULL, 0);
+  tree_view = gtk_tree_view_new_with_model (GTK_TREE_MODEL (sort_model));
   selection = GTK_OBJECT (gtk_tree_view_get_selection (GTK_TREE_VIEW (tree_view)));
   gtk_tree_selection_set_type (GTK_TREE_SELECTION (selection), GTK_TREE_SELECTION_SINGLE);
 
@@ -237,7 +245,7 @@ make_window ()
   /* The selected column */
   cell = gtk_cell_renderer_text_new ();
   column = gtk_tree_view_column_new_with_attributes ("nodes", cell, "text", 0, NULL);
-  gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), GTK_TREE_VIEW_COLUMN (column));
+  gtk_tree_view_append_column (GTK_TREE_VIEW (tree_view), column);
 
   /* A few to start */
   iter_prepend (NULL, GTK_TREE_VIEW (tree_view));
@@ -254,7 +262,7 @@ main (int argc, char *argv[])
   gtk_init (&argc, &argv);
 
   model = gtk_tree_store_new_with_values (2, G_TYPE_STRING, G_TYPE_STRING);
-
+  
   make_window ();
   make_window ();